package be.kdg.bombermanunlimited.client;

import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;

import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

import be.kdg.bombermanunlimited.client.CentralRegistry.BombermanObjects;
import be.kdg.bombermanunlimited.client.gui.BombermanFrame;
import be.kdg.bombermanunlimited.client.gui.game.GamePanel;
import be.kdg.bombermanunlimited.client.gui.listener.WindowFlowListener;
import be.kdg.bombermanunlimited.client.gui.startup.ClientSettings;
import be.kdg.bombermanunlimited.client.network.NetworkFactory;
import be.kdg.bombermanunlimited.client.network.listeners.ErrorListener;
import be.kdg.bombermanunlimited.client.network.listeners.INetworkListener;

public class Main implements WindowFlowListener {

	private BombermanFrame frm;
	private ClientSettings clientSettings;
	private JPanel game;

	public Main() {
		game = null;
		clientSettings = null;
		frm = null;

		SwingUtilities.invokeLater(new Runnable() {

			@Override
			public void run() {
				createGui();
			}
		});
	}

	private void createGui() {
		frm = new BombermanFrame("Bomberman unlimited");
		clientSettings = new ClientSettings(this);
		frm.setContentPane(clientSettings);
		frm.pack();
		frm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frm.setResizable(false);
		frm.centerOnScreen();
		frm.setVisible(true);

		frm.addWindowListener(new FrameListener());
	}

	@Override
	public void nextWindow(JComponent src) {
		if (src == clientSettings) {
			RingErrorListener rel = new RingErrorListener();
			CentralRegistry reg = CentralRegistry.getRegistry();
			NetworkFactory.createNetworkFactory(
					reg.getString(BombermanObjects.HOST_IP),
					reg.getInteger(BombermanObjects.HOST_PORT));
			NetworkFactory.getNetworkFactory().createRingNetwork(
					reg.getInteger(BombermanObjects.RING_PORT), rel, rel);
		} else if (src == game) {
			frm.setVisible(false);
		}
	}

	private void startGameWindow() {
		frm.setContentPane(new GamePanel());
		frm.validate();
		frm.pack();

		CentralRegistry reg = CentralRegistry.getRegistry();
		frm.setTitle(frm.getTitle() + " - "
				+ reg.getString(BombermanObjects.USERNAME));
	}

	private class RingErrorListener implements ErrorListener, INetworkListener {
		@Override
		public void socketInUse() {
			if (clientSettings != null) {
				clientSettings
						.setState("The local port is already in use for this ip!");
			}
		}

		@Override
		public void onConnect() {
		}

		@Override
		public void onDisconnect() {
		}

		@Override
		public void onConnectionLost() {
		}

		@Override
		public void nodeAdded() {
			// System.out.println("[Main] node added");
			startGameWindow();
		}

		@Override
		public void serverFull() {
			if (clientSettings != null) {
				clientSettings
						.setState("Server full!");
			}
		}

	}

	private class FrameListener implements WindowListener {

		@Override
		public void windowOpened(WindowEvent e) {
		}

		@Override
		public void windowClosing(WindowEvent e) {
			NetworkFactory nf = NetworkFactory.getNetworkFactory();
			if (nf != null) {
				if (nf.getRingNetwork() != null) {
					nf.getRingNetwork().disconnect();
				}
			}
		}

		@Override
		public void windowClosed(WindowEvent e) {
		}

		@Override
		public void windowIconified(WindowEvent e) {
		}

		@Override
		public void windowDeiconified(WindowEvent e) {
		}

		@Override
		public void windowActivated(WindowEvent e) {
		}

		@Override
		public void windowDeactivated(WindowEvent e) {
		}

	}

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		try {
			UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} catch (InstantiationException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (UnsupportedLookAndFeelException e) {
			e.printStackTrace();
		}

		new Main();
	}
}
